<template>
  <div>
    <el-table
      ref="multipleDevCreateRef"
      v-model:selected-row-keys="multipleDevCreateList"
      :data="tableData"
      style="width: 100%"
      row-key="Path"
      default-expand-all
      @select="select"
      @select-all="selectAll"
      @selection-change="handleSelectionChange"
      :tree-props="{ children: 'Children' }"
      :row-class-name="tableRowClassName"
    >
      <el-table-column type="selection" width="55" :selectable="selectable" />
      <el-table-column property="Path" label="设备名" width="240" />
      <el-table-column property="TypStr" label="类型" />
      <el-table-column property="Mount" label="挂载点" />
      <el-table-column property="Capacity" label="容量" />
    </el-table>
  </div>
</template>
<script setup lang="tsx" name="roleManager">
import { ref } from "vue";
interface nodeItem {
  Path: string; //路径
  Capacity: string; // 空间
  Parent: string; // 父节点(如果空就是根节点)
  Mount: string; // 挂载点
  Typstr: string; // 类型
  IsUsed: boolean; // 是否使用
  Children?: nodeItem[];
}
const multipleDevCreateRef = ref<InstanceType<typeof ElTable>>();
const multipleDevCreateList = ref<nodeItem[]>([]);
const handleSelectionChange = () => {
  multipleDevCreateList.value = multipleDevCreateRef.value?.getSelectionRows();
};

const tableData = ref<any[]>([
  {
    Capacity: "200.0GB",
    IsUsed: false,
    Mount: "",
    Parent: "",
    Path: "/dev/sdc",
    TypStr: "disk",
    Children: [
      {
        Capacity: "190.GB",
        IsUsed: false,
        Mount: "",
        Parent: "/dev/sdc",
        Path: "/dev/sdc1",
        TypStr: "part"
      },
      {
        Capacity: "9.9GB",
        IsUsed: false,
        Mount: "",
        Parent: "/dev/sdc",
        Path: "/dev/sdc2z",
        TypStr: "part"
      },
      {
        Capacity: "9.9GB",
        IsUsed: false,
        Mount: "",
        Parent: "/dev/sdc",
        Path: "/dev/sdc2z0",
        TypStr: "part"
      }
    ]
  },
  {
    Capacity: "20.0GB",
    IsUsed: false,
    Mount: "",
    Parent: "",
    Path: "/dev/sdd",
    TypStr: "disk",
    Children: [
      {
        Capacity: "19.9GB",
        IsUsed: false,
        Mount: "",
        Parent: "/dev/sdd",
        Path: "/dev/sdd1",
        TypStr: "part"
      }
    ]
  },
  {
    Capacity: "20.0GB",
    IsUsed: false,
    Mount: "",
    Parent: "",
    Path: "/dev/sdb",
    TypStr: "disk",
    Children: [
      {
        Capacity: "19.9GB",
        IsUsed: false,
        Mount: "",
        Parent: "/dev/sdb",
        Path: "/dev/sdb1",
        TypStr: "part"
      }
    ]
  }
]);
const tableRowClassName = ({ row }: { row: nodeItem }) => {
  // 被使用了的设备   颜色加深   原生UI 不太明显
  if (row.IsUsed === true) {
    return "disabled-row";
  } else {
    return "";
  }
};

const selectable = (row: nodeItem) => {
  return row.IsUsed === false;
};

const setChildren = (children: nodeItem[], type: boolean) => {
  // 编辑多个子层级
  children.map((j: nodeItem) => {
    toggleSelection(j, type);
    if (j.Children) {
      setChildren(j.Children, type);
    }
  });
};

// 设置父级选中/取消
const setParent = (currentRow: any, type: boolean, parent: nodeItem[], selectionLists: nodeItem[]) => {
  if (!parent.length) {
    parent = tableData.value;
  }
  let allSelect: any[] = [];
  parent.forEach((item: nodeItem) => {
    if (item.Children) {
      // 注：Parent 是当前选中节点的所有父节点的一个字符串形式的数据，这个很关键
      if (currentRow.Parent === item.Path) {
        // 选中
        if (type) {
          selectionLists.forEach((k: nodeItem) => {
            item.Children?.forEach((j: nodeItem) => {
              if (k.Path == j.Path) {
                allSelect.push(j);
              }
            });
          });
          if (allSelect.length == item.Children.length) {
            toggleSelection(item, type);
            selectionLists.push(item);
            select(selectionLists, item);
          } else {
            setParent(currentRow, type, item.Children, selectionLists);
          }
        } else {
          // 取消选中
          toggleSelection(item, type);
          setParent(currentRow, type, item.Children, []);
        }
      }
    }
  });
};

const toggleSelection = (row: nodeItem, select: boolean) => {
  // 编辑多个子层级
  if (row) {
    multipleDevCreateRef.value?.toggleRowSelection(row, select);
  }
};

// 选中父节点时，子节点一起选中/取消
const select = (selection: nodeItem[], row: nodeItem) => {
  const hasSelect = selection.some((el: nodeItem) => {
    return row.Path === el.Path;
  });
  if (hasSelect) {
    if (row.Children) {
      // 解决子组件没有被勾选到
      setChildren(row.Children, true);
    }
    // 子节点被全勾选，父节点也勾上
    setParent(row, true, [], selection);
  } else {
    if (row.Children) {
      setChildren(row.Children, false);
    }
    // 子级取消选中, 传入当前选中节点, 所有父级取消选中
    setParent(row, false, [], []);
  }
};

// 选择全部
const selectAll = (selection: nodeItem[]) => {
  // tabledata第一层只要有在selection里面就是全选
  const isSelect = selection.some((el: nodeItem) => {
    const tableDataPaths = tableData.value.map((j: nodeItem) => j.Path);
    return tableDataPaths.includes(el.Path);
  });
  // tableDate第一层只要有不在selection里面就是全不选
  const isCancel = !tableData.value.every((el: nodeItem) => {
    const selectPaths = selection.map(j => j.Path);
    return selectPaths.includes(el.Path);
  });
  if (isCancel) {
    tableData.value.map((el: nodeItem) => {
      if (el.Children) {
        // 解决子组件没有被勾选到
        setChildren(el.Children, false);
      }
    });
  }
  if (isSelect) {
    selection.map(el => {
      if (el.Children) {
        // 解决子组件没有被勾选到
        setChildren(el.Children, true);
      }
    });
  }
};
</script>
